package com.hung.triple.serialize;

import com.hung.triple.bootstrap.TripleConsumerConfig;
import com.hung.triple.bootstrap.TripleProviderConfig;
import com.hung.triple.common.enums.TripleSerializerType;
import com.hung.triple.serialize.hessian.HessianSerializer;
import com.hung.triple.serialize.java.JavaSerializer;
import com.hung.triple.serialize.json.FastJsonSerializer;
import com.hung.triple.serialize.kryo.KryoSerializer;
import com.hung.triple.serialize.protobuf.ProtobufSerializer;
import lombok.extern.slf4j.Slf4j;

/**
 * 序列化器工厂
 * 单例模式，因此需要 Serializer 保证线程安全
 *
 * @author Hung
 * @since 2022/9/18
 */
@Slf4j
public final class SerializerFactory {

    private static volatile Serializer serializer;

    /**
     * zookeeper 模式下：从ZK读取配置文件一定要先于该方法的第一次调用
     * 直连模式下：一开始就指定了，因此没关系
     */
    public static Serializer getSerializer(TripleSerializerType tripleSerializerType) {
        if (serializer == null) {
            synchronized (SerializerFactory.class) {
                if (serializer == null) {

                    switch (tripleSerializerType) {
                        case KRYO:
                            serializer = new KryoSerializer();
                            break;
                        case FAST_JSON:
                            serializer = new FastJsonSerializer();
                            break;
                        case PROTOBUF:
                            serializer = new ProtobufSerializer();
                            break;
                        case HESSIAN2:
                            serializer = new HessianSerializer();
                            break;
                        default:
                            serializer = new JavaSerializer();
                            break;
                    }
                    log.info("[Triple] initialized the serializer({}) successful", serializer);
                }
            }
        }
        return serializer;
    }

    public static Serializer getEncodeSerializer() {
        return getSerializer(TripleConsumerConfig.getSerializerType());
    }

    public static Serializer getDecodeSerializer() {
        return getSerializer(TripleProviderConfig.getSerializerType());
    }
}
